<?php

namespace app\common\controller;


use app\lib\exception\ParamException;
use think\Controller;
use think\Db;

class TengxunService extends Controller
{
    protected $account;
    protected $access_token;
    protected $start_date;
    protected $end_date;


    /**
     * 记录系统日志
     * @param string $behavior
     * @param array $arr
     */
    public function RecordSystemLog($uid,$behavior,$description)
    {
        $data['uid'] = $uid;
        $data['ip'] = $this->request->ip();
        $data['behavior'] = $behavior;
        $data['description'] = $description;
        model('SystemLog')->writeSystemLog($data);  // 日志入库
    }

    /**
     * 获取报告
     */
    public function getReportData($acc_id, $yesterday=0)
    {
        $account = Db::name('account')->find($acc_id);

        if($account['syn_status'] != 1){
            throw new ParamException(['msg'=>'账户未开启同步','errorCode'=>10001]);
        }

        if($account['syn_num'] == 0){
            $startDate= date('Y-m-d', strtotime('-1 month'));
        }else{
            if($yesterday){
                $startDate= date('Y-m-d', strtotime('-1 days'));
            }else{
                $startDate= date('Y-m-d');
            }
        }
        $endDate = date('Y-m-d');

        $this->start_date = $startDate;
        $this->end_date = $endDate;

        $this->account = $account;
        $this->access_token = $this->getAccessToken($account);

        $this->getAdvertiserData();
        $this->getCampaignData();
        $this->getAdgroupData();
        $this->getAdData();

        Db::name('account')->where('id', $acc_id)->setInc('syn_num'); // 同步数加1
        return json(['code' => 1001, 'msg' => '未定义消息']);
    }

    // 获取access_token
    public function getAccessToken($account)
    {
        $token_info = Db::name('access_token')->where(['admin_id'=>$account['admin_id'],'channel_id'=>2,'account_id'=>$account['macc_id']])->find();
        if(!$token_info){
            model('Account')->save(['syn_status'=>2],['id'=>$account['id']]);
            throw new ParamException(['msg'=>'未获取到access_token','errorCode'=>30001]);
        }
        return $token_info['access_token'];
    }


    // 广告主数据
    public function getAdvertiserData()
    {
        $level = 'REPORT_LEVEL_ADVERTISER';
        $group_by = ['date'];
        $list = $this->daily_reports_get($level,$group_by);
        if($list){
            foreach ($list as $k=>$v){
                $this->saveReport($v);
            }
        }else{
            $this->RecordSystemLog($this->account['admin_id'],'manage/TengxunService/getAdvertiserData','未获取到腾讯广告主数据');
        }
    }

    // 广告计划数据
    public function getCampaignData()
    {
        $level = 'REPORT_LEVEL_CAMPAIGN';
        $group_by = ['date','campaign_id'];
        $fields = ['campaign_id','campaign_name'];
        $list = $this->daily_reports_get($level,$group_by,$fields);
        if($list){
            foreach ($list as $k=>$v){
                $append = [
                    'campaign_id' => $v['campaign_id'],
                    'campaign_name' => $v['campaign_name']??'未知'
                ];
                $this->saveReport($v,$append);
            }
        }else{
            $this->RecordSystemLog($this->account['admin_id'],'manage/TengxunService/getCampaignData','未获取到腾讯广告计划数据');
        }
    }

    // 广告组数据
    public function getAdgroupData()
    {
        $level = 'REPORT_LEVEL_ADGROUP';
        $group_by = ['date','adgroup_id'];
        $fields = ['campaign_id','adgroup_id','adgroup_name'];
        $list = $this->daily_reports_get($level,$group_by,$fields);
        if($list){
            foreach ($list as $k=>$v){
                $append = [
                    'campaign_id' => $v['campaign_id'],
                    'adgroup_id' => $v['adgroup_id'],
                    'adgroup_name' => $v['adgroup_name']
                ];
                $this->saveReport($v,$append);
            }
        }else{
            $this->RecordSystemLog($this->account['admin_id'],'manage/TengxunService/getAdgroupData','未获取到腾讯广告组数据');
        }
    }

    // 广告创意数据
    public function getAdData()
    {
        $level = 'REPORT_LEVEL_AD';
        $group_by = ['date','ad_id'];
        $fields = ['campaign_id','adgroup_id','ad_id','ad_name'];
        $list = $this->daily_reports_get($level,$group_by,$fields);
        if($list){
            foreach ($list as $k=>$v){
                $append = [
                    'campaign_id' => $v['campaign_id'],
                    'adgroup_id' => $v['adgroup_id'],
                    'ad_id' => $v['ad_id'],
                    'ad_name' => $v['ad_name']
                ];
                $this->saveReport($v,$append);
            }
        }else{
            $this->RecordSystemLog($this->account['admin_id'],'manage/TengxunService/getAdData','未获取到腾讯广告创意数据');
        }
    }

    public function saveReport($v,$append=[])
    {
        $param['date'] = $v['date'];
        $param['adv_id'] = $this->account['adv_id'];
        $param['acc_name'] = $this->account['acc_name'];
        $param['impression'] = $v['view_count'];
        $param['click'] = $v['valid_click_count'];
        $param['cost'] = $v['cost'];
        $param['ctr'] = $v['ctr'];
        $param['cpc'] = $v['cpc'];
        $param['cpm'] = $v['thousand_display_price'];
        $param['conversions_count'] = $v['conversions_count'];
        $param['conversions_cost'] = $v['conversions_cost'];
        $param['conversions_rate'] = $v['conversions_rate'];
        $where = [
            'date'=>$v['date'],
            'adv_id'=>$this->account['adv_id'],
            'campaign_id'=>$append['campaign_id'] ?? 0,
            'adgroup_id'=>$append['adgroup_id'] ?? 0,
            'ad_id'=>$append['ad_id'] ?? 0,
        ];
        $param['admin_id'] = $this->account['admin_id'];
        $param['create_time'] = time();
        $param['update_time'] = time();

        $param = array_merge($param, $append);

        if($this->account['syn_num'] == 0){
            $res_db = Db::name('tengxun_report')->insert($param);
            if(!$res_db){
                trace($param,'error');
            }
        }else{
            $one = model('TengxunReport')->where($where)->find();
            if($one){
                model('TengxunReport')->where('id',$one['id'])->delete();
            }
            $res_db = Db::name('tengxun_report')->insert($param);
            if(!$res_db){
                trace($param,'error');
            }
        }
    }

    // 获取每日数据
    public function daily_reports_get($level,$group_by,$fields=[])
    {
        $interface = 'daily_reports/get';
        $url = 'https://api.e.qq.com/v1.1/' . $interface;

        $common_parameters = array (
            'access_token' => $this->access_token,
            'timestamp' => time(),
            'nonce' => md5(uniqid('', true))
        );

        $parameters = array (
            'account_id' => $this->account['adv_id'],
            'level' => $level,
            'date_range' => [
                    'start_date' => $this->start_date,
                    'end_date' => $this->end_date,
               ],

            'group_by' => $group_by,
            'order_by' => [
                [
                    'sort_field' => 'date',
                    'sort_type' => 'DESCENDING'
                ]
            ],
            'page' => 1,
            'page_size' => 1000,
            'fields' =>array_merge(['account_id','date','view_count','thousand_display_price','valid_click_count','ctr','cpc','cost','conversions_rate','conversions_count','conversions_cost'],$fields)
        );

        $parameters = array_merge($common_parameters, $parameters);

        foreach ($parameters as $key => $value) {
            if (!is_string($value)) {
                $parameters[$key] = json_encode($value);
            }
        }

        $request_url = $url . '?' . http_build_query($parameters);

        $res_json = curl_get($request_url);
        $res = json_decode($res_json, true);
        if($res['code'] != 0){
            trace($res_json,'error');
            model('Account')->save(['syn_status'=>2],['id'=>$this->account['id']]);
            throw new ParamException(['msg'=>$res['message'] ?? '获取腾讯报告失败','errorCode'=>30003]);
        }else{
            $list =  $res['data']['list'] ?? [];
            if($list){
                return $list;
            }else{
                $this->RecordSystemLog($this->account['admin_id'],'manage/TengxunService/daily_reports_get','未获取到腾讯渠道账户【'.$level.'】数据');
            }
        }
    }

    // 获取落地页列表
    public function getPageList($account)
    {
        $access_token = $this->getAccessToken($account);
        $interface = 'pages/get';
        $url = 'https://api.e.qq.com/v1.1/' . $interface;

        $common_parameters = array (
            'access_token' => $access_token,
            'timestamp' => time(),
            'nonce' => md5(uniqid('', true))
        );

        $parameters = array (
            'account_id' => $account['adv_id'],
            'promoted_object_type' => 'PROMOTED_OBJECT_TYPE_LEAD_AD',
            'fields' => ['page_id','page_name','preview_url','created_time'],
            'page' => 1,
            'page_size' => 100,
        );

        $parameters = array_merge($common_parameters, $parameters);

        foreach ($parameters as $key => $value) {
            if (!is_string($value)) {
                $parameters[$key] = json_encode($value);
            }
        }

        $request_url = $url . '?' . http_build_query($parameters);

        $res_json = curl_get($request_url);trace($res_json,'error');
        $res = json_decode($res_json, true);
        if($res['code'] == 0){
            return $res['data']['list'];
        }else{
            trace($res_json,'error');
            throw new ParamException(['msg'=>$res['message'] ?? '落地页同步失败','errorCode'=>30002]);
        }
    }
}